﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Xml;
using System.ServiceModel.Description;
using System.Web;
using System.IO;
using System.Collections.Specialized;

namespace WebServices
{
    // The implementation of our web service.
    public class WebServiceImpl : WebService
    {
        // DbAccess object, abstracts away the process of connecting to the database.
        private DbAccess dbAccess = null;

        public WebServiceImpl()
        {
            this.dbAccess = new DbAccess(false);
        }

        ~WebServiceImpl()
        {
            this.dbAccess = null;
        }

        public XmlDocument GetCategories()
        {
            return this.dbAccess.GetCategories();
        }

        public XmlDocument GetUserInfoByUID(string uid)
        {
            return this.dbAccess.GetUserInfoByUID(uid);
        }

        /*public XmlDocument GetUserPostByCat(string categoryType)
        {
            return this.dbAccess.GetUserPostByCat(categoryType);
        }*/

        public XmlDocument GetUserPostByZip(string zip)
        {
            return this.dbAccess.GetUserPostByZip(zip);
        }

        public XmlDocument CreateAccount(Stream input)
        {
            XmlDocument toReturn = null;
            string data = new StreamReader(input).ReadToEnd();
            NameValueCollection createParameters = HttpUtility.ParseQueryString(data);
            string userId = createParameters["UserId"];
            string firstName = createParameters["FirstName"];
            string lastName = createParameters["LastName"];
            string birthday = createParameters["Birthday"];
            string zip = createParameters["Zip"];
            string email = createParameters["Email"];
            string password = createParameters["Password"];
            if (userId == null ||
                firstName == null ||
                lastName == null ||
                birthday == null ||
                zip == null ||
                email == null ||
                password == null)
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Missing field</Reason></Result>");
            }
            else
            {
                toReturn = this.dbAccess.CreateAccount(userId, firstName, lastName, birthday, zip, email, password);
            }
            return toReturn;
        }

        public XmlDocument Login(Stream input)
        {
            XmlDocument toReturn = null;
            string data = new StreamReader(input).ReadToEnd();
            NameValueCollection createParameters = HttpUtility.ParseQueryString(data);
            string userId = createParameters["UserId"];
            string password = createParameters["Password"];

            if (userId == null || password == null)
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Missing field</Reason></Result>");
            }
            else
            {
                toReturn = this.dbAccess.Login(userId, password);
            }
            return toReturn;
        }

        public XmlDocument MakePost(Stream data)
        {
            XmlDocument toReturn = null;
            NameValueCollection postParameters = HttpUtility.ParseQueryString(new StreamReader(data).ReadToEnd());
            string title = postParameters["Title"];
            string date = DateTime.Now.ToString("yyyy-MM-dd");
            string link = postParameters["Link"];
            string imageUrl = postParameters["ImageURL"];
            string description = postParameters["Description"];
            string zip = postParameters["Zip"];
            string sessionId = postParameters["SessionID"];
            string categoryTitle = postParameters["CategoryTitle"];
            if (title == null ||
                link == null ||
                imageUrl == null ||
                description == null ||
                zip == null ||
                sessionId == null ||
                categoryTitle == null)
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Missing field</Reason></Result>");
            }
            else if (title == "" ||
                     description == "" ||
                     imageUrl == "" ||
                     zip == "")
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Required field was empty</Reason></Result>");
            }
            else
            {
                toReturn = this.dbAccess.MakePost(title, date, link, imageUrl, description, zip, sessionId, categoryTitle);
            }
            return toReturn;
        }

        public XmlDocument MakeComment(Stream data)
        {
            XmlDocument toReturn = null;
            NameValueCollection postParameters = HttpUtility.ParseQueryString(new StreamReader(data).ReadToEnd());
            string postId = postParameters["PostId"];
            string sessionId = postParameters["SessionId"];
            string comment = postParameters["Comment"];
            if (postId == null ||
                sessionId == null ||
                comment == null)
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Missing field</Reason></Result>");
            }
            else if (postId == "" ||
                     sessionId == "" ||
                     comment == "")
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Required field was empty</Reason></Result>");
            }
            else
            {
                toReturn = this.dbAccess.MakeComment(postId, sessionId, comment);
            }
            return toReturn;
        }

        public XmlDocument GetComments(Stream data)
        {
            XmlDocument toReturn = null;
            NameValueCollection postParameters = HttpUtility.ParseQueryString(new StreamReader(data).ReadToEnd());
            string postId = postParameters["PostId"];
            if (postId == null)
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Missing field</Reason></Result>");
            }
            else if (postId == "")
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Required field was empty</Reason></Result>");
            }
            else
            {
                toReturn = this.dbAccess.GetComments(postId);
            }
            return toReturn;
        }

        public XmlDocument Logout(Stream data)
        {
            XmlDocument toReturn = null;
            NameValueCollection postParameters = HttpUtility.ParseQueryString(new StreamReader(data).ReadToEnd());
            string userId = postParameters["UserId"];
            if (userId == null)
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Missing field</Reason></Result>");
            }
            else if (userId == "")
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Required field was empty</Reason></Result>");
            }
            else
            {
                toReturn = this.dbAccess.Logout(userId);
            }
            return toReturn;
        }

        public XmlDocument RatePost(Stream data)
        {
            XmlDocument toReturn = null;
            NameValueCollection postParameters = HttpUtility.ParseQueryString(new StreamReader(data).ReadToEnd());
            string sessionId = postParameters["SessionId"];
            string postId = postParameters["PostId"];
            string rating = postParameters["Rating"];
            if (sessionId == null ||
                postId == null ||
                rating == null)
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Missing field</Reason></Result>");
            }
            else if (sessionId == "" ||
                     postId == "" ||
                     rating == "")
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Required field was empty</Reason></Result>");
            }
            else
            {
                toReturn = this.dbAccess.RatePost(sessionId, postId, rating);
            }

            return toReturn;
        }

        public XmlDocument GetUserRatingForPost(Stream data)
        {
            XmlDocument toReturn = null;
            NameValueCollection postParameters = HttpUtility.ParseQueryString(new StreamReader(data).ReadToEnd());
            string sessionId = postParameters["SessionId"];
            string postId = postParameters["PostId"];
            if (sessionId == null ||
                postId == null)
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Missing field</Reason></Result>");
            }
            else if (sessionId == "" ||
                     postId == "")
            {
                toReturn = new XmlDocument();
                toReturn.LoadXml("<Result><Success>False</Success><Reason>Required field was empty</Reason></Result>");
            }
            else
            {
                toReturn = this.dbAccess.GetUserRatingForPost(sessionId, postId);
            }

            return toReturn;
        }

        /**********************************************************************
         * UNIT TEST ONLY BELOW HERE                                          *
         **********************************************************************/
        public XmlDocument RunUnitTests()
        {
            return new WebServicesUnitTest(this, this.dbAccess).RunUnitTests();
        }

    }
}
